package io.renren.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import dm.jdbc.util.StringUtil;
import io.renren.common.exception.RenException;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.dao.*;
import io.renren.dto.*;
import io.renren.dto.queryDto.BillCode2Query;
import io.renren.entity.*;
import io.renren.factory.FeginClientFactory;
import io.renren.service.*;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ${comments}
 *
 * @author Sen 524227263@qq.com
 * @since 1.0.0 2024-05-30
 */
@Service
public class MakecardvouchersdServiceImpl extends CrudServiceImpl<MakecardvouchersdDao, MakecardvouchersdEntity, MakecardvouchersdDTO> implements MakecardvouchersdService {

    @Autowired
    private SysparamDao sysparamDao;
    @Autowired
    private AutoDao autoDao;
    @Autowired
    private CardvoucherschangemDao cardvoucherschangemDao;
    @Autowired
    private MakecardvouchersmDao makecardvouchersmDao;
    @Autowired
    private ChangecardvouchersdDao changecardvouchersdDao;
    @Autowired
    private AutoService autoService;
    @Autowired
    private SysparamService sysparamService;
    @Autowired
    private GoodsmDao goodsmDao;

    @Override
    public QueryWrapper<MakecardvouchersdEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<MakecardvouchersdEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(id), "id", id);

        return wrapper;
    }


    @Override
    public List<List<Map<String, Object>>> couponsList(String traderMOID, CouponsDto dto) {
        Map<String, Object> result = new HashMap<>();
        String whereSql = "";
        if (StringUtil.isNotEmpty(dto.getQuery())) {
            whereSql = "  and CardName like '%" + dto.getQuery() + "%' ";
        }
        if (StringUtil.isNotEmpty(dto.getOrderByTime())) {
            if (dto.getOrderByTime().equals("1")) {
                whereSql += " order by EndDate asc";
            } else {
                whereSql += " order by EndDate desc";
            }
        }

        List<Map<String, Object>> mapList = baseDao.querySql(traderMOID, whereSql);
        SysparamEntity sysparamEntity = sysparamDao.selectOne(new QueryWrapper<SysparamEntity>().eq("Name", "CompName"));
        String companyName = sysparamEntity != null ? sysparamEntity.getValue() : "";


        List<Object> newEntryOs = new ArrayList<>();

        // Initialize result map
        Map<String, Map<String, Object>> res = new HashMap<>();

        for (int i = 0; i < mapList.size(); i++) {
            List<Map<String, Object>> couponList = new ArrayList<>();
            Map<String, Object> v = mapList.get(i);
            String CardVouchersRuleMFK = v.get("CardVouchersRuleM_FK").toString();

            if (!res.containsKey(v.get("CardVouchersRuleM_FK"))) {
                Map<String, Object> newItem = new HashMap<>();
                Map<String, Object> item = new HashMap<>();
                // 二级数据
                item.put("MakeCardVouchersDOID", v.get("MakeCardVouchersDOID"));
                item.put("CardVouchersCode", v.get("CardVouchersCode"));

                item.put("StartDate", v.get("StartDate") != null ? v.get("StartDate") : "");
                item.put("EndDate", v.get("EndDate") != null ? v.get("EndDate") : "");
                item.put("AutoNo", v.get("AutoNo"));
                item.put("ROW_NUMBER", 1);
                AutoEntity autoEntity = autoService.findOneByAutoNo(v.get("AutoNo") + "");
                item.put("Auto_FK", autoEntity != null ? autoEntity.getAutooid() : ""); // 假设这是一个方法
                couponList.add(item);

                // 一级数据
                newItem.put("IsAutoUse", v.get("IsAutoUse"));
                newItem.put("AutoNo", v.get("AutoNo"));
                newItem.put("companyName", companyName); // 假设有一个 companyName 变量
                newItem.put("ROW_NUMBER", 1);
                newItem.put("couponName", v.get("CardName"));
                newItem.put("couponNum", 1);
                newItem.put("canGift", v.get("IsDonation"));
                newItem.put("StartDate", v.get("EndDate") != null ? v.get("EndDate") : "");
                newItem.put("EndDate", v.get("EndDate") != null ? v.get("EndDate") : "");
                newItem.put("GoodsM_FK", v.get("GoodsM_FK"));
                newItem.put("couponList", couponList);

                res.put(CardVouchersRuleMFK, newItem);
            } else {
                String oldStartDate = res.get(v.get("CardVouchersRuleM_FK")).get("StartDate").toString();
                if (oldStartDate.compareTo(v.get("StartDate").toString()) > 0) {
                    res.get(v.get("CardVouchersRuleM_FK")).put("StartDate", v.get("StartDate"));
                }
                String oldEndDate = res.get(v.get("CardVouchersRuleM_FK")).get("EndDate").toString();
                if (oldEndDate.compareTo(v.get("EndDate").toString()) < 0) {
                    res.get(v.get("CardVouchersRuleM_FK")).put("EndDate", v.get("EndDate"));
                }

                int couponNum = (int) res.get(v.get("CardVouchersRuleM_FK")).get("couponNum") + 1;
                res.get(v.get("CardVouchersRuleM_FK")).put("couponNum", couponNum);

                List<Map<String, Object>> couponListOIld = (List<Map<String, Object>>) res.get(v.get("CardVouchersRuleM_FK")).get("couponList");
                ;
                // 如果存在，则更新已有条目
                Map<String, Object> coupon = new HashMap<>();
                coupon.put("MakeCardVouchersDOID", v.get("MakeCardVouchersDOID"));
                coupon.put("ROW_NUMBER", couponNum);
                coupon.put("CardVouchersCode", v.get("CardVouchersCode"));
                String couStartTime = v.get("StartDate") != null ? v.get("StartDate").toString() : "";
                coupon.put("StartDate", couStartTime);
                String couEndTime = v.get("EndDate") != null ? v.get("EndDate").toString() : "";
                coupon.put("EndDate", couEndTime);
                coupon.put("AutoNo", v.get("AutoNo"));
                AutoEntity autoEntity = autoService.findOneByAutoNo(v.get("AutoNo") + "");
                coupon.put("Auto_FK", autoEntity != null ? autoEntity.getAutooid() : ""); // 假设这是一个方法
                couponListOIld.add(coupon);
            }
        }

        Map<String, List<Map<String, Object>>> data = new HashMap<>();

        for (String outerKey : res.keySet()) {
            System.out.println("Outer Key: " + outerKey);
            // 获取内层 Map 对象
            Map<String, Object> innerMap = res.get(outerKey);
            String companyName2 = (String) innerMap.get("companyName");
            if (data.containsKey(companyName)) {
                data.get(companyName).add(innerMap);
            } else {
                List<Map<String, Object>> list = new ArrayList<>();
                list.add(innerMap);
                data.put(companyName, list);
            }
        }
        List<List<Map<String, Object>>> values = new ArrayList<>(data.values());
        return values;
    }

    private Long getCountByTraderMFK(String traderMOID) {
        return baseDao.selectCount(new QueryWrapper<MakecardvouchersdEntity>().eq("TraderM_FK", traderMOID).eq("SentFlag", 2));
    }


    private List<MakecardvouchersdEntity> findMakeCardVouchersMFk(String traderMOID) {
        return baseDao.selectList(new QueryWrapper<MakecardvouchersdEntity>()
                .select("distinct(MakeCardVouchersM_FK)")
                .eq("SentFlag", 2)
                .eq("TraderM_FK", traderMOID)
                .gt("EndDate", new Date()));
    }

    private List<MakecardvouchersdEntity> findMakeCardVouchersMFk2(String traderMOID) {
        return baseDao.selectList(new QueryWrapper<MakecardvouchersdEntity>()
                .select("distinct(MakeCardVouchersM_FK)")
                .ne("SentFlag", 2)
                .eq("TraderM_FK", traderMOID));
    }

    // 辅助方法：将日期格式化成字符串
    private static String formatDate(String date) {
        // 实现日期格式化逻辑
        return date; // 假设直接返回原字符串
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> sendCoupons(String traderMOID, SendCouponsDto dto) {
        List<MakecardvouchersdEntity> list = baseDao.selectList(new QueryWrapper<MakecardvouchersdEntity>()
                .in("MakeCardVouchersDOID", dto.getCouponsIds().split(",")));
        boolean flag = true;
        for (MakecardvouchersdEntity entity : list) {
            if (!entity.getTradermFk().equals(traderMOID) || !entity.getSentflag().equals("2")) {
                flag = false;
                break;
            }
        }
        if (!flag) {
            throw new RenException("卡券状态异常");
        }

        // 赠送卡券
        // 根据车牌号查询车辆是否存在，不存在则新增
        AutoEntity autoEntity = autoDao.selectOne(new QueryWrapper<AutoEntity>().eq("AutoNo", dto.getAutoNo()));
        String autooid = "";
        if (autoEntity == null) {
            AutoEntity autoNew = new AutoEntity();
            autooid = UUID.randomUUID().toString();
            autoNew.setAutooid(autooid);
            autoNew.setAutono(dto.getAutoNo());
            autoNew.setSysCreated(new Date());
            autoNew.setSysLastUpd(new Date());
            autoNew.setRegistrationdate(new Date());
            autoNew.setNowmileage(new BigDecimal(0));
            autoDao.insert(autoNew);
        } else {
            autooid = autoEntity.getAutooid();
        }
        List<String> couponIds = Arrays.asList(dto.getCouponsIds().split(","));
        for (String couponId : couponIds) {
            MakecardvouchersdEntity makecardvouchersdEntity = baseDao.selectOne(new QueryWrapper<MakecardvouchersdEntity>()
                    .eq("MakeCardVouchersDOID", couponId));
            if (makecardvouchersdEntity != null) {
                MakecardvouchersdEntity upInfo = new MakecardvouchersdEntity();
                upInfo.setAutoFk(autooid);
                upInfo.setTradermFk(null);
                upInfo.setSentflag("1");
                upInfo.setSysLastUpd(new Date());
                upInfo.setSendertradermFk(makecardvouchersdEntity.getTradermFk());
                upInfo.setSenderautoFk(makecardvouchersdEntity.getAutoFk());
                baseDao.update(upInfo, new QueryWrapper<MakecardvouchersdEntity>().eq("MakeCardVouchersDOID", couponId));
            }
        }

        return Collections.emptyMap();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> acceptCoupons(String traderMOID, AcceptCouponsDto dto) {
        List<String> couponIds = Arrays.asList(dto.getCouponsIds().split(","));

        List<MakecardvouchersdEntity> list = baseDao.selectList(new QueryWrapper<MakecardvouchersdEntity>()
                .in("MakeCardVouchersDOID", couponIds));
        boolean flag = true;
        //        for (MakecardvouchersdEntity entity : list) {
        //            if (entity.getTradermFk() != traderMOID || !entity.getSentflag().equals("2")) {
        //                flag = false;
        //                break;
        //            }
        //        }
        //        if (!flag) {
        //            throw new RenException("卡券状态异常");
        //        }

        BillCode2Query query = new BillCode2Query();
        query.setEncodeKind("CVC");
        ReturnApiDto result = FeginClientFactory.getFeginClient(FeginClientProxy.class, "http://58.216.180.2:8405/").getBillCode2(query);
        String billcode = result.getData().toString();

        MakecardvouchersdEntity makecardvouchersdEntity = baseDao.selectOne(new QueryWrapper<MakecardvouchersdEntity>()
                .eq("MakeCardVouchersDOID", couponIds.get(0)));

        String cardvoucherschangemoid = UUID.randomUUID().toString();
        CardvoucherschangemEntity cardvoucherschangemEntity = new CardvoucherschangemEntity();
        cardvoucherschangemEntity.setCardvoucherschangemoid(cardvoucherschangemoid);
        cardvoucherschangemEntity.setSysCreated(new Date());
        cardvoucherschangemEntity.setBilltype("CVC");
        cardvoucherschangemEntity.setBilldate(new Date());
        cardvoucherschangemEntity.setBillcode(billcode);
        cardvoucherschangemEntity.setTradermFk(traderMOID);
        cardvoucherschangemEntity.setAutoFk(makecardvouchersdEntity.getAutoFk());
        cardvoucherschangemEntity.setChangereason("转赠");
        cardvoucherschangemEntity.setEffdate(new Date());
        cardvoucherschangemDao.insert(cardvoucherschangemEntity);

        for (String couponId : couponIds) {
            MakecardvouchersdEntity makecardvouchersdInfo = baseDao.selectOne(new QueryWrapper<MakecardvouchersdEntity>()
                    .eq("MakeCardVouchersDOID", couponId));
            if (makecardvouchersdInfo != null) {
                makecardvouchersdInfo.setSentflag("2");
                makecardvouchersdInfo.setTradermFk(traderMOID);
                makecardvouchersdInfo.setSysLastUpd(new Date());

                baseDao.update(makecardvouchersdEntity, new QueryWrapper<MakecardvouchersdEntity>()
                        .eq("MakeCardVouchersDOID", couponId));

                MakecardvouchersmEntity makecardvouchersmEntity = makecardvouchersmDao.selectOne(new QueryWrapper<MakecardvouchersmEntity>()
                        .eq("MakeCardVouchersMOID", makecardvouchersdInfo.getMakecardvouchersmFk()));

                ChangecardvouchersdEntity info = new ChangecardvouchersdEntity();
                info.setChangecardvouchersdoid(UUID.randomUUID().toString());
                info.setCardvoucherschangemFk(cardvoucherschangemoid);
                info.setMakecardvouchersmFk(makecardvouchersdInfo.getMakecardvouchersmFk());
                info.setMakecardvouchersdFk(couponId);
                info.setOldtradermFk(makecardvouchersdInfo.getSendertradermFk());
                info.setOldautoFk(makecardvouchersdInfo.getSenderautoFk());
                info.setOldenddate(info.getEnddate());
                info.setOldstartdate(info.getStartdate());
                info.setGoodsmFk(makecardvouchersmEntity != null ? makecardvouchersmEntity.getGoodsmFk() : null);
                changecardvouchersdDao.insert(info);
            }
        }

        return Collections.emptyMap();
    }

    @Override
    public void refuseCoupon(String makeCardVouchersDOID) {
        List<String> ids = Arrays.asList(makeCardVouchersDOID.split(","));
        for (String id : ids) {
            MakecardvouchersdEntity makecardvouchersdEntity = baseDao.selectOne(new QueryWrapper<MakecardvouchersdEntity>()
                    .eq("MakeCardVouchersDOID", id));
            if (makecardvouchersdEntity != null) {
                MakecardvouchersdEntity updateInfo = new MakecardvouchersdEntity();

                updateInfo.setAutoFk(makecardvouchersdEntity.getSenderautoFk());
                updateInfo.setTradermFk(makecardvouchersdEntity.getSendertradermFk());
                updateInfo.setSentflag("2");
                updateInfo.setSysLastUpd(new Date());
                updateInfo.setSendertradermFk(null);
                updateInfo.setSenderautoFk(null);
                baseDao.update(updateInfo, new QueryWrapper<MakecardvouchersdEntity>()
                        .eq("MakeCardVouchersDOID", id));
            }
        }

    }
}